﻿using IDAdmin.Lib.DataLayer;
using System;
using System.Collections.Generic;
using System.Data;
using System.Globalization;
using System.Linq;
using System.Reflection;
using System.Web;

namespace IDAdmin.Common
{
    public static class ConverterWorkData
    {
        public static DateTime kindUnixTimeStampToKindDateTime(double unixTimeStamp, DateTimeKind kindUnixTime, DateTimeKind kindDateTime)
        {
            // Unix timestamp is seconds past epoch
            System.DateTime dtDateTime = new DateTime(1970, 1, 1, 0, 0, 0, 0, kindUnixTime);
            if (kindDateTime.Equals(DateTimeKind.Local))
            {
                dtDateTime = dtDateTime.AddSeconds(unixTimeStamp).ToLocalTime();
                return dtDateTime;
            }
            else
                if (kindDateTime.Equals(DateTimeKind.Utc))
                {
                    dtDateTime = dtDateTime.AddSeconds(unixTimeStamp).ToUniversalTime();
                    return dtDateTime;
                }
            return DateTime.Now;
        }

        public static DateTime ConvertFromUnixTimestamp(double timestamp)
        {
            DateTime origin = new DateTime(1970, 1, 1, 0, 0, 0, 0);
            return origin.AddSeconds(timestamp);
        }
        public static double kindDateTimeToKindUnixTimestamp(DateTime date, DateTimeKind kind)
        {
            DateTime origin = new DateTime(1970, 1, 1, 0, 0, 0, 0, kind);
            TimeSpan diff = date - origin;
            return Math.Floor(diff.TotalSeconds);
        }
        public static string truncateTime(string timeStamp, string format)
        {
            //"dd/MM/yyyy HH:mm"
            if (string.IsNullOrEmpty(format))
            {
                format = "dd/MM/yyyy HH:mm";
            }
            // string strDt = ConverterWorkData.ConvertFromUnixTimestamp(double.Parse(timeStamp)).ToString(format);
            //DateTime dtTemp = TimeZone.CurrentTimeZone.ToLocalTime(DateTime.ParseExact(strDt, format, CultureInfo.InvariantCulture));
            //string timeStampTemp = ConverterWorkData.ConvertToUnixTimestamp(dtTemp).ToString();
            string strlocalTime = ConverterWorkData.kindUnixTimeStampToKindDateTime(double.Parse(timeStamp), DateTimeKind.Local, DateTimeKind.Local).ToString(format);// sủa từ utc timestamp sang local timestamp
            double localTimeStamp = ConverterWorkData.kindDateTimeToKindUnixTimestamp(DateTime.ParseExact(strlocalTime, format, CultureInfo.InvariantCulture), DateTimeKind.Local);
            return localTimeStamp.ToString();
        }
        /*Converts List To DataTable*/
        public static List<DateTime> getDateListBetween(DateTime fromDate, DateTime toDate)
        {
            var dates = new List<DateTime>();

            for (var dt = fromDate; dt <= toDate; dt = dt.AddDays(1))
            {
                dates.Add(dt);
            }
            return dates;
        }
        public static DateTime convertStringToDateTime(string date)
        {
            string[] dateArrray = date.Split('/');
            DateTime dt = new DateTime(int.Parse(dateArrray[2]), int.Parse(dateArrray[1]), int.Parse(dateArrray[0]));
            return dt;
        }

        public static DataTable ToDataTable<TSource>(this IList<TSource> data, int type, int additionLength)
        {
            DataTable dataTable = new DataTable(typeof(TSource).Name);
            PropertyInfo[] props = typeof(TSource).GetProperties(BindingFlags.Public | BindingFlags.Instance);
            foreach (PropertyInfo prop in props)
            {
                dataTable.Columns.Add(prop.Name, Nullable.GetUnderlyingType(prop.PropertyType) ??
                    prop.PropertyType);
            }
            foreach (TSource item in data)
            {
                var values = new object[props.Length + additionLength];
                for (int i = 0; i < props.Length; i++)
                {
                    values[i] = props[i].GetValue(item, null);
                    if (type == 0)
                    {
                        if (i == 7)
                        {
                            //WorkDataStatistics.ServerName = new List<string>();
                            List<Ccu> ccuServerList = (List<Ccu>)values[7];
                            int count = 8;
                            foreach (Ccu ccu in ccuServerList)
                            {
                                if (ccu != null && dataTable.Columns.Contains(ccu.GameZone) == false)
                                {
                                    dataTable.Columns.Add(ccu.GameZone);
                                    //WorkDataStatistics.ServerName.Add(ccu.GameZone);
                                }
                                values[count] = ccu.Num;
                                count++;
                            }
                        }
                    }
                    else
                        if (type == 1)
                        {
                            if (i == 4)
                            {
                                //WorkDataStatistics.ServerName = new List<string>();
                                List<Acu> ccuAverageList = (List<Acu>)values[4];
                                int count = 5;
                                foreach (Acu acu in ccuAverageList)
                                {
                                    if (acu != null && dataTable.Columns.Contains(acu.GameZone) == false)
                                    {
                                        dataTable.Columns.Add(acu.GameZone);
                                        //WorkDataStatistics.ServerName.Add(acu.GameZone);
                                    }
                                    values[count] = acu.Average;
                                    count++;
                                }
                            }
                        }
                        else
                            if (type == 2)
                            {
                                if (i == 4)
                                {
                                    //WorkDataStatistics.ServerName = new List<string>();
                                    List<Pcu> CcuMaxServerList = (List<Pcu>)values[4];
                                    int count = 5;
                                    foreach (Pcu pcu in CcuMaxServerList)
                                    {
                                        if (pcu != null && dataTable.Columns.Contains(pcu.GameZone) == false)
                                        {
                                            dataTable.Columns.Add(pcu.GameZone);
                                            //WorkDataStatistics.ServerName.Add(pcu.GameZone);
                                        }
                                        values[count] = pcu.Max;
                                        count++;
                                    }
                                }
                            }
                            else
                                if (type == 4)
                                {
                                    if (i == 3)
                                    {
                                        List<PeopleNumAndPercentServer> pnapsList = (List<PeopleNumAndPercentServer>)values[3];
                                        int count = 4;
                                        foreach (var pnaps in pnapsList)
                                        {
                                            if (pnaps != null && dataTable.Columns.Contains(pnaps.GameZone+"ServerPeopleNum") == false && dataTable.Columns.Contains(pnaps.GameZone+"ServerPeopleNumPercent") == false)
                                            {
                                                dataTable.Columns.Add(pnaps.GameZone + "ServerPeopleNum");
                                                dataTable.Columns.Add(pnaps.GameZone + "ServerPeopleNumPercent");
                                            }
                                            values[count] = pnaps.PeopleNum;
                                            values[++count] = pnaps.PeopleNumPercent;
                                            count++;
                                        }

                                    }
                                }

                }
                dataTable.Rows.Add(values);
            }
            return dataTable;
        }

        /*Converts DataTable To List*/
        public static List<TSource> ToList<TSource>(this DataTable dataTable) where TSource : new()
        {
            var dataList = new List<TSource>();

            const BindingFlags flags = BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic;
            var objFieldNames = (from PropertyInfo aProp in typeof(TSource).GetProperties(flags)
                                 select new
                                 {
                                     Name = aProp.Name,
                                     Type = Nullable.GetUnderlyingType(aProp.PropertyType) ??
                             aProp.PropertyType
                                 }).ToList();
            var dataTblFieldNames = (from DataColumn aHeader in dataTable.Columns
                                     select new
                                     {
                                         Name = aHeader.ColumnName,
                                         Type = aHeader.DataType
                                     }).ToList();
            var commonFields = objFieldNames.Intersect(dataTblFieldNames).ToList();

            foreach (DataRow dataRow in dataTable.AsEnumerable().ToList())
            {
                var aTSource = new TSource();
                foreach (var aField in commonFields)
                {
                    PropertyInfo propertyInfos = aTSource.GetType().GetProperty(aField.Name);
                    var value = (dataRow[aField.Name] == DBNull.Value) ?
                    null : dataRow[aField.Name]; //if database field is nullable
                    propertyInfos.SetValue(aTSource, value, null);
                }
                dataList.Add(aTSource);
            }
            return dataList;
        }

    }
}